#include "jsapi.h"
#include "js-engine.h"
#include "desktopClasses.h"
#include "basicElementClass.h"
#include "mainview-parser.h"

static JSBool progressbar_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval);
static JSBool progressbar_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
static gboolean draw_progressbar(GtkWidget *widget, GdkEventExpose *event, gpointer ptr);

static JSFunctionSpec progressbar_methods[] = {
    {NULL, NULL, 0, 0, 0}
};

JSClass progressbarClass =
    { "progressbar", JSCLASS_HAS_PRIVATE,
      JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, progressbar_SetProperty,
      JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub,
      JSCLASS_NO_OPTIONAL_MEMBERS
    };

struct property_parser progressbar_parser[] = {
    /* from basicElement */
    {"cursor", set_property_string_value},
    {"dropTarget", set_property_boolean_value},
    {"enabled", set_property_boolean_value},
    {"height", set_property_integer_value},
    {"hitTest", set_property_string_value},
    {"mask", set_property_string_value},
    {"name", set_property_string_value},
    {"offsetHeight", set_property_integer_value},
    {"offsetWidth", set_property_integer_value},
    {"offsetX", set_property_integer_value},
    {"offsetY", set_property_integer_value},
    {"opacity", set_property_integer_value},
    {"pinX", set_property_integer_value},
    {"pinY", set_property_integer_value},
    {"rotation", set_property_float_value},
    {"tagName", set_property_string_value},
    {"tooltip", set_property_string_value},
    {"width", set_property_integer_value},
    {"visible", set_property_boolean_value},
    {"x", set_property_integer_value},
    {"y", set_property_integer_value},
		
    {"emptyImage", set_property_string_value},
    {"fullImage", set_property_string_value},
    {"max", set_property_integer_value},
    {"min", set_property_integer_value},
    {"orientation", set_property_string_value},
    {"thumbDisabledImage", set_property_string_value},
    {"thumbDownImage", set_property_string_value},
    {"thumbOverImage", set_property_string_value},
    {"thumbImage", set_property_string_value},
    {"value", set_property_integer_value},
		
    {ONCLICK, set_property_function_value},
    {ONRCLICK, set_property_function_value},
    {ONDBLCLICK, set_property_function_value},
    {ONRDBLCLICK, set_property_function_value},
    {"ondragdrop", set_property_function_value},
    {"ondragover", set_property_function_value},
    {ONFOCUSIN, set_property_function_value},
    {ONFOCUSOUT, set_property_function_value},
    {ONKEYDOWN, set_property_function_value},
    {ONKEYPRESS, set_property_function_value},
    {ONKEYUP, set_property_function_value},
    {ONMOUSEDOWN, set_property_function_value},
    {ONMOUSEMOVE, set_property_function_value},
    {ONMOUSEOUT, set_property_function_value},
    {ONMOUSEOVER, set_property_function_value},
    {ONMOUSEUP, set_property_function_value},
    {ONMOUSEWHEEL, set_property_function_value},
    {NULL, NULL},
};

static JSBool progressbar_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
{
    gchar *key;
    desktop_element *element = JS_GetPrivate(cx, obj);
    key = JS_GetStringBytes(JS_ValueToString(cx, id));

    g_return_val_if_fail(element, JS_FALSE);
    if (element->view == NULL)
        return JS_TRUE;

    if(g_strcasecmp(key, "value") == 0)
	desktop_element_call_handler(element, ONCHANGE);

    basicElement_SetProperty(cx, obj, id, vp);
    gtk_widget_queue_draw(element->view);
    
    return JS_TRUE;
}

static JSBool progressbar_new(JSContext *cx, JSObject *obj, uintN argc, jsval *args, jsval *rval)
{
    return JS_TRUE;
}

JSObject *progressbarClass_init(js_engine *engine, JSObject *parent)
{
    JSObject *proto = NULL;
    proto = JS_InitClass(engine->cx, engine->glob, parent,
			 &progressbarClass, progressbar_new,
			 0,NULL,NULL,NULL,NULL);
    g_return_val_if_fail(proto, FALSE);
    g_return_val_if_fail(JS_DefineFunctions(engine->cx, proto, progressbar_methods), FALSE);
    return proto;
}

static gboolean draw_progressbar(GtkWidget *widget, GdkEventExpose *event, gpointer ptr)
{

    jsval emptyImage = JSVAL_VOID,
	fullImage = JSVAL_VOID,
	value_rval = JSVAL_VOID,
	opacity_rval = JSVAL_VOID,
	x_rval = JSVAL_VOID,
	y_rval = JSVAL_VOID;
    desktop_element *element = (desktop_element *)ptr;
    cairo_t *cr = NULL;
    cairo_surface_t *empty_surface = NULL,
	*full_surface = NULL;
    guint ratio = 0, opacity = 255;
    gint width_val = -1, height_val = -1, x=0, y=0;
    gchar *emptyImgPath, *fullImgPath;
    cr = gdk_cairo_create(widget->window);
	
    JS_GetProperty(element->engine->cx, element->jsobj, "emptyImage", &emptyImage);
    JS_GetProperty(element->engine->cx, element->jsobj, "fullImage", &fullImage);
    JS_GetProperty(element->engine->cx, element->jsobj, "value", &value_rval);
    JS_GetProperty(element->engine->cx, element->jsobj, "opacity", &opacity_rval);
    JS_GetProperty(element->engine->cx, element->jsobj, "x", &x_rval);
    JS_GetProperty(element->engine->cx, element->jsobj, "y", &y_rval);
		
    emptyImgPath = trans_unix_path_new(JS_GetStringBytes(JS_ValueToString(element->engine->cx, emptyImage)));
    fullImgPath = trans_unix_path_new(JS_GetStringBytes(JS_ValueToString(element->engine->cx, fullImage)));
    empty_surface = cairo_image_surface_create_from_png(emptyImgPath);
    full_surface = cairo_image_surface_create_from_png(fullImgPath);
    g_free(emptyImgPath);
    g_free(fullImgPath);
    width_val = MAX(cairo_image_surface_get_width(empty_surface), 
		    cairo_image_surface_get_width(full_surface));
    height_val = MAX(cairo_image_surface_get_height(empty_surface), 
		     cairo_image_surface_get_height(full_surface));

    if(JSVAL_IS_INT(value_rval)){
	if(JSVAL_TO_INT(value_rval) < 0)
	    ratio = 0;
	else if(JSVAL_TO_INT(value_rval) > 100)
	    ratio = 100;
	else{
	    ratio = JSVAL_TO_INT(value_rval);
	}
    }

    if(JSVAL_IS_INT(opacity_rval)){
	opacity = JSVAL_TO_INT(opacity_rval);
	if(opacity < 0)
	    opacity = 0;
	else if(opacity > 255)
	    opacity = 255;
    }
    if(JSVAL_IS_INT(x_rval))
	x = JSVAL_TO_INT(x_rval);
    if(JSVAL_IS_INT(y_rval))
	y = JSVAL_TO_INT(y_rval);
    
    cairo_set_source_surface(cr, empty_surface, 0, 0);
    cairo_paint_with_alpha(cr, (gdouble)opacity/255);
		
    cairo_rectangle(cr, 0, 0, width_val*ratio/100, height_val);
    cairo_clip(cr);
    cairo_set_source_surface(cr, full_surface, 0, 0);
    cairo_paint_with_alpha(cr, (gdouble)opacity/255);

    gtk_widget_set_size_request(element->view, width_val, height_val);
    cairo_destroy(cr);
    return FALSE;
}

void desktop_element_set_view_progressbar(js_engine *engine, desktop_element *element)
{
    element->view = gtk_drawing_area_new();
    gtk_widget_add_events(element->view,GDK_ALL_EVENTS_MASK);
    g_signal_connect(element->view, "expose-event", 
		     G_CALLBACK(draw_progressbar), element);
    set_element_event_cb(element);
    gtk_widget_show_all(element->view);
}
